home *** CD-ROM | disk | FTP | other *** search
/ NOVA - For the NeXT Workstation / NOVA - For the NeXT Workstation.iso / SourceCode / AdobeExamples / NX_Binary / EpsfParser.m < prev    next >
Encoding:
Text File  |  1992-12-19  |  6.0 KB  |  287 lines

  1.  
  2. /*
  3.  * (a)  (C) 1990 by Adobe Systems Incorporated. All rights reserved.
  4.  *
  5.  * (b)  If this Sample Code is distributed as part of the Display PostScript
  6.  *    System Software Development Kit from Adobe Systems Incorporated,
  7.  *    then this copy is designated as Development Software and its use is
  8.  *    subject to the terms of the License Agreement attached to such Kit.
  9.  *
  10.  * (c)  If this Sample Code is distributed independently, then the following
  11.  *    terms apply:
  12.  *
  13.  * (d)  This file may be freely copied and redistributed as long as:
  14.  *    1) Parts (a), (d), (e) and (f) continue to be included in the file,
  15.  *    2) If the file has been modified in any way, a notice of such
  16.  *      modification is conspicuously indicated.
  17.  *
  18.  * (e)  PostScript, Display PostScript, and Adobe are registered trademarks of
  19.  *    Adobe Systems Incorporated.
  20.  * 
  21.  * (f) THE INFORMATION BELOW IS FURNISHED AS IS, IS SUBJECT TO
  22.  *    CHANGE WITHOUT NOTICE, AND SHOULD NOT BE CONSTRUED
  23.  *    AS A COMMITMENT BY ADOBE SYSTEMS INCORPORATED.
  24.  *    ADOBE SYSTEMS INCORPORATED ASSUMES NO RESPONSIBILITY
  25.  *    OR LIABILITY FOR ANY ERRORS OR INACCURACIES, MAKES NO
  26.  *    WARRANTY OF ANY KIND (EXPRESS, IMPLIED OR STATUTORY)
  27.  *    WITH RESPECT TO THIS INFORMATION, AND EXPRESSLY
  28.  *    DISCLAIMS ANY AND ALL WARRANTIES OF MERCHANTABILITY, 
  29.  *    FITNESS FOR PARTICULAR PURPOSES AND NONINFRINGEMENT
  30.  *    OF THIRD PARTY RIGHTS.
  31.  */
  32.  
  33. /*
  34. *    EpsfParser.m
  35. *
  36. *    This class reads in a distilled epsf file and attempts to parse through the file
  37. *    and insert the paths into the programs data structures.
  38.  *
  39.  *    Version:    2.0
  40.  *    Author:    Ken Fromm
  41.  *    History:
  42.  *            03-07-91        Added this comment.
  43. */
  44.  
  45. #import "EpsfParser.h"
  46. #import "iparser.h"
  47. #import <appkit/Panel.h>
  48. #import <appkit/nextstd.h>
  49. #import <stdio.h>
  50.  
  51. static char  *processToLineEnd();
  52. static char  *processToField();
  53.  
  54. static BOOL checkForPS(char **dataptr, float *level_dsc, float *level_epsf)
  55. {
  56.     char     *dp;
  57.     
  58.     BOOL    invalid_ps = YES;
  59.  
  60.     *level_dsc = *level_epsf = 0.0;
  61.  
  62.     dp = *dataptr;
  63.     if (!strncmp(dp, "%!PS-Adobe-", 11))
  64.     {
  65.         invalid_ps = NO;
  66.  
  67.         dp +=11;
  68.         sscanf(dp, "%f", level_dsc);
  69.  
  70.         while(*dp == ' ') dp++;
  71.         if (!strncmp(dp, "EPSF-", 5))
  72.         {
  73.             dp += 5;
  74.             sscanf(dp, "%f", level_dsc);
  75.         }
  76.     }
  77.     
  78.     *dataptr = processToLineEnd(dp);
  79.  
  80.     return invalid_ps;
  81. }
  82.  
  83. static int checkType(char *s0, char *s1, char *s2, char *s3)
  84. {
  85.     int    type = PS_NOTYPE;
  86.     
  87.     if (s0 && *s0 && s1 && *s1)
  88.     {
  89.         if (!strncmp(s0, "Adobe", 5) && !strncmp(s1, "Illustrator", 11))
  90.             type = PS_ILLUSTRATOR;
  91.         else if (!strncmp(s0, "Glenn", 5) &&
  92.                 !strncmp(s1, "Reid", 4) &&
  93.                 !strncmp(s3, "still.ps", 8))
  94.             type = PS_DISTILLERY;
  95.     }
  96.  
  97.     return type;
  98. }
  99.  
  100. static BOOL validateCreator(int ps_creator)
  101. {
  102.     if (ps_creator == PS_DISTILLERY)
  103.         return YES;
  104.     else
  105.         return NO;
  106. }
  107.  
  108. static void convertBounds(float *aBox, NXRect *aRect)
  109. {
  110.     aRect->origin.x = aBox[0];
  111.     aRect->origin.y = aBox[1];
  112.     aRect->size.width = aBox[2] - aBox[0];
  113.     aRect->size.height = aBox[3] - aBox[1];
  114. }
  115.             
  116. static char *processToLineEnd(char *dp)
  117. {
  118.     dp = strchr(dp,'\n'); dp++;
  119.     
  120.     return dp;
  121. }
  122.  
  123. static char *processToField(char *dp)
  124. {
  125.  
  126.     dp = strchr(dp,':'); dp++;
  127.     if (*dp == ' ')
  128.     {
  129.         strrchr(dp, ' ');
  130.         dp++;
  131.     }
  132.     
  133.     return dp;
  134. }
  135.  
  136. static void  checkHeader(char **dataptr, float *bbox, BOOL *validBBox, int  *creator)
  137. {
  138.     BOOL    done = NO;
  139.  
  140.     char        *dp;
  141.     
  142.     char        str0[40], str1[40], str2[40], str3[40];
  143.  
  144.     int        matches = 0;
  145.  
  146.     *creator = PS_NOTYPE;
  147.     *validBBox = NO;
  148.  
  149.     dp = *dataptr;
  150.     while (*dp && !done)
  151.     {
  152.         if (strncmp(dp, "%%", 2) == 0)
  153.         {
  154.             dp += 2;
  155.             if (strncmp(dp, "EndComments", 11) == 0)
  156.                 done = YES;
  157.             else if (strncmp(dp, "Creator:", 8) == 0)
  158.             {
  159.                 dp = processToField(dp);
  160.                 sscanf(dp, "%s%s%s%s", str0, str1, str2, str3);
  161.                 *creator = checkType(str0, str1, str2, str3);
  162.             }
  163.             else if (strncmp(dp, "BoundingBox:", 12) == 0)
  164.             {
  165.                 dp = processToField(dp);
  166.                 if (strncmp(dp, "(atend)", 7) != 0)
  167.                 {
  168.                     matches = sscanf(dp, "%f %f %f %f",
  169.                         &bbox[0], &bbox[1], &bbox[2], &bbox[3]);
  170.                     if ((matches && matches != 4) ||
  171.                          (matches == 4 &&
  172.                         (bbox[2] == bbox[0] || bbox[3] == bbox[1])))
  173.                         *validBBox = YES;
  174.                 }
  175.             }
  176.         }    
  177.         dp = processToLineEnd(dp);
  178.     }
  179.  
  180.     *dataptr = dp;
  181.     return;
  182. }
  183.  
  184. static void  checkTrailer(char **dataptr, float *bbox, BOOL *validBBox)
  185. {
  186.     BOOL    done = NO;
  187.  
  188.     char        *dp;
  189.     
  190.     int        matches = 0;
  191.  
  192.     *validBBox = NO;
  193.  
  194.     dp = *dataptr;
  195.     while (*dp && !done)
  196.     {
  197.         if (strncmp(dp, "%%", 2) == 0)
  198.         {
  199.             dp += 2;
  200.             if (strncmp(dp, "BoundingBox:", 12) == 0)
  201.             {
  202.                 dp = processToField(dp);
  203.                 matches = sscanf(dp, "%f %f %f %f",
  204.                         &bbox[0], &bbox[1], &bbox[2], &bbox[3]);
  205.                 if (matches == 4 && bbox[2] != bbox[0] && bbox[3] != bbox[1])
  206.                  {
  207.                      done = YES;
  208.                     *validBBox = YES;
  209.                 }
  210.             }
  211.         }
  212.         dp = processToLineEnd(dp);
  213.     }
  214.  
  215.     *dataptr = dp;
  216.     return;
  217. }
  218.  
  219. @implementation EpsfParser
  220.  
  221. /*
  222.  * Checks for valid PS file, gets the bounding box and checks for
  223.  * the creator. The creator will let us determine whether we can read
  224.  * the file into our own graphics structure.
  225.  */
  226. - readPSFromStream:(NXStream *)stream
  227. {
  228.     BOOL    error = YES, validBBox = NO;
  229.  
  230.     char     *data;
  231.     
  232.     float        bbox[4];
  233.  
  234.     int         length,        /* the number of bytes in data */
  235.             maxlen;        /* size of vm_allocated region */
  236.  
  237.     bbox[0] = bbox[1] = bbox[2] = bbox[3] = 0;
  238.     NXGetMemoryBuffer(stream, &data, &length, &maxlen);
  239.     if (length)
  240.     {
  241.         error = checkForPS(&data, &level_dsc, &level_epsf);
  242.         if (!error)
  243.         {
  244.             checkHeader(&data, bbox, &validBBox, &creator);
  245.             if (validateCreator(creator))
  246.             {
  247.                 if (!iparse(&data))
  248.                 {
  249.                     if (!validBBox)
  250.                         checkTrailer(&data, bbox, &validBBox);
  251.                     
  252.                     if (validBBox)
  253.                         convertBounds(bbox, &bounds);    
  254.                     else
  255.                         NXRunAlertPanel("Load File",
  256.                         "Invalid bounding box. Cannot open.", 
  257.                         "OK", NULL, NULL);
  258.                 }
  259.             }
  260.             else
  261.                 NXRunAlertPanel("Load File",
  262.                     "Not a distilled file. Cannot open.", 
  263.                     "OK", NULL, NULL);
  264.         }
  265.         else
  266.             NXRunAlertPanel("Load File", "Not a valid PS file. Cannot open.", 
  267.                     "OK", NULL, NULL);    
  268.     }
  269.     else
  270.         NXRunAlertPanel("Load File", "Invalid file. Cannot open.", 
  271.                 "OK", NULL, NULL);    
  272.  
  273.     if (error)
  274.         return nil;
  275.     else
  276.         return self;
  277. }
  278.  
  279. - getBounds:(NXRect *) aRect
  280. {
  281.     *aRect = bounds;
  282.     return self;
  283. }
  284.  
  285. @end
  286.  
  287.